package com.java.second_goods.controller;

import com.java.second_goods.common.AjaxResult;
import com.java.second_goods.common.utils.FileUtils;
import com.java.second_goods.common.utils.Md5Utils;
import com.java.second_goods.entity.GoodsImage;
import com.java.second_goods.service.IGoodsImageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 商品图片信息
 */
@RestController
@RequestMapping("/api/goods/image")
@Tag(name = "商品图片管理", description = "商品图片相关接口")
public class GoodsImageController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(GoodsImageController.class);

    @Autowired
    private IGoodsImageService goodsImageService;

    @Value("${file.upload.path}")
    private String uploadPath;

    @Value("${file.upload.allowed-types}")
    private String allowedTypes;

    @Value("${file.upload.max-size}")
    private long maxFileSize;

    /**
     * 获取商品的图片列表
     */
    @GetMapping("/list/{goodsId}")
    @Operation(summary = "获取商品图片列表", description = "根据商品ID获取图片列表")
    public AjaxResult list(@PathVariable("goodsId") Integer goodsId) {
        List<GoodsImage> list = goodsImageService.selectImagesByGoodsId(goodsId);
        return success(list);
    }

    /**
     * 获取图片详细信息
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取图片详细信息", description = "根据图片ID获取详细信息")
    public AjaxResult getInfo(@PathVariable("id") Integer id) {
        return success(goodsImageService.getById(id));
    }

    /**
     * 新增图片
     */
    @PostMapping
    @Operation(summary = "新增图片", description = "新增商品图片")
    public AjaxResult add(@RequestBody GoodsImage goodsImage) {
        return toAjax(goodsImageService.insertGoodsImage(goodsImage));
    }

    /**
     * 批量上传图片
     */
    @PostMapping("/upload")
    @Operation(summary = "批量上传图片", description = "批量上传商品图片")
    public AjaxResult upload(@RequestParam("files") MultipartFile[] files,
                             @RequestParam("goodsId") Integer goodsId,
                             HttpServletRequest request) {
        if (files == null || files.length == 0) {
            return error("上传文件不能为空");
        }

        if (goodsId == null || goodsId <= 0) {
            return error("商品ID不能为空");
        }

        List<GoodsImage> imagesList = new ArrayList<>();

        for (int i = 0; i < files.length; i++) {
            MultipartFile file = files[i];

            if (file.isEmpty()) {
                continue; // 跳过空文件
            }

            // 检查文件大小
            if (file.getSize() > maxFileSize) {
                return error("文件大小不能超过" + (maxFileSize / 1024 / 1024) + "MB");
            }

            // 获取文件名
            String fileName = file.getOriginalFilename();

            // 检查文件类型
            String fileExtension = getFileExtension(fileName);
            if (StringUtils.isEmpty(fileExtension) || !isAllowedExtension(fileExtension)) {
                return error("不支持的文件类型，仅支持：" + allowedTypes);
            }

            try {
                // 构建保存路径
                String baseUploadPath = getBaseUploadPath();
                String datePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
                String targetDirectory = baseUploadPath + datePath;

                // 创建目录
                File directory = new File(targetDirectory);
                if (!directory.exists()) {
                    boolean mkdirResult = directory.mkdirs();
                    if (!mkdirResult) {
                        logger.error("无法创建目录: {}", targetDirectory);
                        return error("服务器无法创建目录，请联系管理员");
                    }
                }

                // 生成唯一文件名
                String encryptedFileName = generateEncryptedFileName(fileName);
                String fileFullPath = targetDirectory + File.separator + encryptedFileName + "." + fileExtension;

                // 保存文件
                File targetFile = new File(fileFullPath);
                file.transferTo(targetFile);
                logger.info("商品图片上传成功：{}", fileFullPath);

                // 构建访问URL
                String accessUrl = "/uploads/" + datePath.replace('\\', '/') + "/" + encryptedFileName + "." + fileExtension;

                // 创建商品图片记录
                GoodsImage goodsImage = new GoodsImage();
                goodsImage.setGoodsId(goodsId);
                goodsImage.setSortOrder(i);
                goodsImage.setImageUrl(accessUrl);
                goodsImage.setIsMain(i == 0 ? 1 : 0); // 第一张设为主图
                goodsImage.setStatus(1);

                imagesList.add(goodsImage);
            } catch (IOException e) {
                logger.error("商品图片上传失败: ", e);
                return error("图片上传失败：" + e.getMessage());
            }
        }

        if (imagesList.isEmpty()) {
            return error("没有有效的图片上传");
        }

        // 批量保存图片记录
        int result = goodsImageService.batchInsertImages(imagesList);

        if (result > 0) {
            return success("上传成功", imagesList);
        } else {
            return error("图片记录保存失败");
        }
    }

    /**
     * 修改图片
     */
    @PutMapping
    @Operation(summary = "修改图片", description = "修改商品图片")
    public AjaxResult edit(@RequestBody GoodsImage goodsImage) {
        return toAjax(goodsImageService.updateGoodsImage(goodsImage));
    }

    /**
     * 设置主图
     */
    @PutMapping("/setMain/{id}")
    @Operation(summary = "设置主图", description = "设置商品主图")
    public AjaxResult setMain(@PathVariable("id") Integer id) {
        return toAjax(goodsImageService.setMainImage(id));
    }

    /**
     * 删除图片
     */
    @DeleteMapping("/{ids}")
    @Operation(summary = "删除图片", description = "删除商品图片")
    public AjaxResult remove(@PathVariable Integer[] ids) {
        // 获取图片路径信息并删除物理文件
        for (Integer id : ids) {
            GoodsImage image = goodsImageService.getById(id);
            if (image != null && StringUtils.hasText(image.getImageUrl())) {
                deleteImageFile(image.getImageUrl());
            }
        }
        return toAjax(goodsImageService.deleteGoodsImageByIds(ids));
    }

    /**
     * 删除商品的所有图片
     */
    @DeleteMapping("/deleteByGoodsId/{goodsId}")
    @Operation(summary = "删除商品的所有图片", description = "根据商品ID删除所有图片")
    public AjaxResult removeByGoodsId(@PathVariable("goodsId") Integer goodsId) {
        // 获取所有图片
        List<GoodsImage> images = goodsImageService.selectImagesByGoodsId(goodsId);
        // 删除物理文件
        for (GoodsImage image : images) {
            if (image != null && StringUtils.hasText(image.getImageUrl())) {
                deleteImageFile(image.getImageUrl());
            }
        }
        return toAjax(goodsImageService.deleteImagesByGoodsId(goodsId));
    }

    /**
     * 删除图片文件
     */
    private boolean deleteImageFile(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            return false;
        }

        // 防止路径遍历攻击
        if (filePath.contains("..") || filePath.contains("../")) {
            logger.warn("尝试删除非法路径: {}", filePath);
            return false;
        }

        String baseUploadPath = getBaseUploadPath();
        String fullPath = baseUploadPath + filePath.replace("/uploads/", "");

        // 删除文件
        return FileUtils.deleteFile(fullPath);
    }

    /**
     * 获取基础上传路径
     */
    private String getBaseUploadPath() {
        File uploadDir = new File(uploadPath);
        if (!uploadDir.isAbsolute()) {
            String userDir = System.getProperty("user.dir");
            return userDir + File.separator + uploadPath;
        }
        return uploadPath;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        if (StringUtils.isEmpty(fileName)) {
            return null;
        }

        int lastDotIndex = fileName.lastIndexOf(".");
        if (lastDotIndex < 0) {
            return null;
        }

        return fileName.substring(lastDotIndex + 1).toLowerCase();
    }

    /**
     * 检查文件扩展名是否允许
     */
    private boolean isAllowedExtension(String extension) {
        String[] allowed = allowedTypes.split(",");
        for (String type : allowed) {
            if (type.trim().equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 生成加密的文件名
     */
    private String generateEncryptedFileName(String originalFileName) {
        String uniqueStr = originalFileName + System.currentTimeMillis() + Math.random();
        return Md5Utils.hash(uniqueStr);
    }
}